#!/usr/bin/env python
#
#       mainwindow.py
#
#
#       Copyright (C) 2011 Joe Tannenbaum <jtannen1@binghamton.edu>
#
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
#

import gobject
import os, sys, time, shutil
import pygtk
pygtk.require("2.0")
import gtk
import gtk.glade

NAME = 'Page Archive'

def notification(message): # from SoundConverter 1.4.4
    pass
try:
    import pynotify
    if pynotify.init("Basics"):
        def notification(message):
            n = pynotify.Notification(NAME, message)
            n.show()
except ImportError:
    pass

def update():
    """Refreshes GTK """
    while gtk.events_pending():
        gtk.main_iteration(False)

class MainWindow(object):
    """MainWindow GTK+ class"""

    folder_selected = None
    folder_selected_idex = -1
    page_selected = None
    page_selected_idex = -1
    folder_focus = True
    page_focus = False
    folder = ''
    pages = []

    def __init__(self, archive):
        self.archive = archive

        builder = gtk.Builder()
        builder.add_from_file("mainwindow.xml")

        self.window = builder.get_object("window")

        self.window = builder.get_object("mainwindow")
        self.rename_window = builder.get_object("dialog_rename")
        self.rename_text = 'How did you do this'
        dic = {
            'on_mainwindow_destroy' : self.on_tb_quit_clicked,

            'on_tb_newfolder_clicked' : self.on_tb_newfolder_clicked,
            'on_tb_remove_clicked' : self.on_tb_remove_clicked,
            'on_tb_rename_clicked' : self.on_tb_rename_clicked,
            'on_tb_view_clicked' : self.on_tb_view_clicked,
            'on_tb_scan_clicked' : self.on_tb_scan_clicked,
            'on_tb_quit_clicked' : self.on_tb_quit_clicked,

            'on_button_ok_clicked' : self.on_button_ok_clicked,
            'on_button_cancel_clicked' : self.on_button_cancel_clicked,
        }
        builder.connect_signals(dic)

        # Folders treeview setup
        self.tv_folders = builder.get_object("tv_folders")
        self.ls_folders = gtk.ListStore(gobject.TYPE_STRING,
                                    gobject.TYPE_STRING)
        self.tv_folders.set_model(self.ls_folders)
        renderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Folder", renderer, text=0)
        self.tv_folders.get_selection().connect("changed",
                            self.on_folder_selection_changed)
        self.tv_folders.append_column(column)
        self.tv_folders.get_selection().set_mode(gtk.SELECTION_MULTIPLE)

        # Pages treeview setup
        self.tv_pages = builder.get_object("tv_pages")
        self.ls_pages = gtk.ListStore(gobject.TYPE_STRING,
                                    gobject.TYPE_STRING)
        self.tv_pages.set_model(self.ls_pages)
        renderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Page", renderer, text=0)
        self.tv_pages.get_selection().connect("changed",
                            self.on_pages_selection_changed)
        self.tv_pages.append_column(column)
        self.tv_pages.get_selection().set_mode(gtk.SELECTION_MULTIPLE)

        # Statusbar
        statusbar = builder.get_object('statusbar')
        self.context_id = statusbar.get_context_id('Statusbar')

        # Populate tv_folders
        for foldername in sorted(self.archive.folders):
            self.add_folder_row(foldername)

        self.builder = builder
        gtk.main()

    #
    # Signal Handlers
    #

    def on_folder_selection_changed(self, w):
        selected_rows = self.tv_folders.get_selection().get_selected_rows()
        self.folder_focus = True
        self.page_focus = False
        if selected_rows[1]:
            self.folder_selected_idex = [a[0] for a in selected_rows[1]][0]
            self.folder_selected = selected_rows[0][self.folder_selected_idex][0]

            # remove all the items in self.ls_pages
            self.clear_pages()

            # get new pages
            self.refresh_pages()


            # populate self.ls_pages
            for page in self.pages:
                self.add_page_row(page['name'])#
            self.set_status('Total pages: %i' % len(self.pages))
        else:
            self.clear_pages()


    def on_pages_selection_changed(self, w):
        selected_pages = self.tv_pages.get_selection().get_selected_rows()
        if selected_pages[1]:
            self.page_selected_idex = [a[0] for a in selected_pages[1]][0]
            self.page_selected = selected_pages[0][self.page_selected_idex][0]

            self.folder_focus = False
            self.page_focus = True

            selected_page = self.pages[self.page_selected_idex]
            self.set_status('Created on '+selected_page['date'])


    def on_tb_newfolder_clicked(self, w):
        self.rename_text = ''
        self.rename_window.run()
        self.rename_window.hide()
        self.builder.get_object("entry_new_name").set_text('')
        update()
        if self.rename_text:
            if not self.rename_text in self.archive.db.keys():
                # create folder in self.archive
                self.archive.make_folder(self.rename_text)

                # add entry in self.tv_folders
                self.add_folder_row(self.rename_text)
            else:
                print 'Folder of name %s already exists!' % self.rename_text

    def on_tb_remove_clicked(self, w):
        if self.folder_focus and self.folder_selected:
            self.archive.remove_folder(self.folder_selected)
            self.remove_folder_row(self.folder_selected)
            self.clear_pages()
        elif self.page_focus and self.page_selected:
            self.archive.remove_page(self.folder_selected, self.page_selected_idex)
            self.remove_page_row(self.pages[self.page_selected_idex]['name'])
            self.refresh_pages()

    def on_tb_rename_clicked(self, w):
        self.rename_text = ''
        if self.folder_focus:
            self.builder.get_object("entry_new_name").set_text(self.folder_selected)
        elif self.page_focus:
            self.builder.get_object("entry_new_name").set_text(self.page_selected)
        self.rename_window.run()
        self.rename_window.hide()
        self.builder.get_object("entry_new_name").set_text('')
        update()
        if self.rename_text:
            if self.folder_focus:
                self.archive.rename_folder(self.folder_selected, self.rename_text)
                selected_iter = self.ls_folders.get_iter(self.folder_selected_idex)
                self.ls_folders.set_value(selected_iter, 0, self.rename_text)
                self.folder_selected = self.rename_text
            else:
                self.archive.rename_page(self.folder_selected, self.page_selected_idex, self.rename_text)
                selected_iter = self.ls_pages.get_iter(self.page_selected_idex)
                self.ls_pages.set_value(selected_iter, 0, self.rename_text)
                self.refresh_pages()
                self.page_selected = self.rename_text

    def on_tb_view_clicked(self, w):
        if self.page_focus:
            selected_page = self.pages[self.page_selected_idex]
            imgpath = os.path.join(self.archive.config["PROFILE"], '\ '.join(self.folder_selected.split()), selected_page['filename'])
            # TODO: make where the folders are part of config
            os.system('%s %s' % (self.archive.config["VIEWER"], imgpath))
            #+tdo

    def on_tb_scan_clicked(self, w):
        self.rename_text = ''
        self.rename_window.run()
        self.rename_window.hide()
        self.builder.get_object("entry_new_name").set_text('')
        update()
        if self.rename_text:
            self.rename_text = self.rename_text.replace('`','')
            print 'Scanning...'
            self.window.set_sensitive(False)

            scanfile = str(int(time.time()))+'.tiff'
            imgstring = self.rename_text+'`'+scanfile
            datafile = os.path.join(self.archive.config['PROFILE'], '\ '.join(self.folder_selected.split()), scanfile)
            os.system('%s > %s' % (self.archive.config["SCANCMD"], datafile))

            self.archive.make_page(self.folder_selected, self.rename_text, scanfile)
            self.add_page_row(self.rename_text)
            self.refresh_pages()

            self.window.set_sensitive(True)
            if self.folder_focus:
                self.set_status('Total pages: %i' % len(self.pages))

            notification('Finished scanning %s' % self.rename_text)

    def on_tb_quit_clicked(self, w):
        print 'Exiting!'
        sys.exit(0)#


    def on_button_ok_clicked(self, w):
        self.rename_text = self.builder.get_object("entry_new_name").get_text()
        self.builder.get_object("entry_new_name").set_text('')

    def on_button_cancel_clicked(self, w):
        self.builder.get_object("entry_new_name").set_text('')
        self.rename_text = ''



    #
    # Treeview Methods
    #

    def add_folder_row(self, foldername):
        """Adds a row to folder list with string foldername"""
        myiter = self.ls_folders.append()
        self.ls_folders.set_value(myiter, 0, foldername)

    def remove_folder_row(self, foldername):
        """Removes row(s) from folder list with string foldername"""
        foldernames = [row[0] for row in self.ls_folders]
        for name in foldernames:
            if foldername == name:
                idex = foldernames.index(name)
                self.ls_folders.remove(self.ls_folders.get_iter(idex))
                break

    def add_page_row(self, pagename):
        """Adds a row to page list with string pagename"""
        myiter = self.ls_pages.append()
        self.ls_pages.set_value(myiter, 0, pagename)

    def remove_page_row(self, pagename):
        """Removes row(s) from page list with string foldername"""
        self.page_selected = None
        self.page_selected_idex = -1
        pagenames = [row[0] for row in self.ls_pages]
        for name in pagenames:
            if pagename == name:
                idex = pagenames.index(name)
                self.ls_pages.remove(self.ls_pages.get_iter(idex))
                break

    def clear_pages(self):
        for page in self.pages:
            self.remove_page_row(page['name'])
        self.pages = []
        self.page_selected = None
        self.page_selected_idex = -1

    #
    # Misc. Methods
    #

    def refresh_pages(self):
        self.pages = [dict(zip(('name','filename'),page)) for page in self.archive.get_pages(self.folder_selected)]
        for page in self.pages:
            ltime = time.localtime(int(page['filename'].split('.')[0]))
            page['date'] = time.strftime("%a, %d %b %Y %H:%M:%S", ltime)

    def set_status(self, s=''):
        """Changes statusbar """
        self.builder.get_object('statusbar').pop(self.context_id)
        self.builder.get_object('statusbar').push(self.context_id, s)
        update()
